package com.xxl.sso.server.service.impl;

import com.alibaba.algo.cooperation.common.BaseResult;
import com.xxl.sso.core.api.SysCacheFeignService;
import com.xxl.sso.core.entity.vo.req.SysCacheAddUpdateReqVO;
import com.xxl.sso.core.entity.vo.req.SysCacheKeyCacheValueReqVO;
import com.xxl.sso.core.entity.vo.req.SysCacheKeyReqVO;
import com.xxl.sso.core.entity.vo.res.SysCacheResVO;
import com.xxl.sso.core.user.XxlSsoUser;
import com.xxl.sso.server.config.XxlSsoCacheConfig;
import com.xxl.sso.server.core.result.ReturnT;
import com.xxl.sso.server.service.SysCacheService;
import com.xxl.sso.server.util.JedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Set;


@Slf4j
@RestController
public class SysCacheFeignServiceImpl implements SysCacheFeignService {

    @Autowired
    private SysCacheService sysCacheService;

    @Value("${xxl.sso.mysqlSubstitute:false}")
    private boolean mysqlSubstitute;

    /**
     * 根据caheKey获取cacheValueObj
     *
     * @return
     */
    @Override
    public BaseResult<SysCacheResVO> cacheValAqusitionByCacheKey(@RequestBody SysCacheKeyReqVO vo) {
        log.info("SysCacheController cacheValAqusitionByCacheKey() executed.param is {}", vo.getCacheKey());
        if (mysqlSubstitute) {
            if (ObjectUtils.isEmpty(vo) || ObjectUtils.isEmpty(vo.getCacheKey())) {
                log.error("SysCacheController cacheEvictionByCacheKey() param cacheKey is null");
                return BaseResult.buildError("SysCacheController cacheValAqusitionByCacheKey() param cacheKey is null.");
            }
            ReturnT<SysCacheResVO> result = sysCacheService.findByCacheKey(vo.getCacheKey());
            if (ReturnT.FAIL_CODE != result.getCode()) {
                log.debug("###############SysCacheController cacheValAqusitionByCacheKey in mysql, cacheKey:{},xxlSsoUser:{}", result.getData().getCacheKey(), result.getData().getCacheValueObj());
                log.info("SysCacheController cacheValAqusitionByCacheKey() successfully executed.");
                return BaseResult.buildSuccess(result.getData());
            } else {
                log.error("SysCacheController cacheValAqusitionByCacheKey() failed to execute.");
                return BaseResult.buildError("SysCacheController cacheValAqusitionByCacheKey() failed to execute.");
            }
        } else {
            if (!ObjectUtils.isEmpty(vo) && !ObjectUtils.isEmpty(vo.getCacheKey())) {
                Object objectValue = JedisUtil.getObjectValue(vo.getCacheKey());
                XxlSsoUser xxlUser = (XxlSsoUser) objectValue;
                SysCacheResVO sysCacheResVO = new SysCacheResVO();
                sysCacheResVO.setCacheKey(vo.getCacheKey());
                sysCacheResVO.setCacheValueObj(xxlUser);
                log.info("###############SysCacheController cacheValAqusitionByCacheKey in redis, cacheKey:{},xxlSsoUser:{}", vo.getCacheKey(), xxlUser);
                return BaseResult.buildSuccess(sysCacheResVO);
            } else {
                log.error("SysCacheController cacheValAqusitionByCacheKey() objectValue is null.");
                return BaseResult.buildSuccess(null);
            }
        }
    }

    /**
     * 根据caheKey新增或更新cache
     *
     * @return
     */
    @Override
    public BaseResult cacheRefreshing(@RequestBody SysCacheAddUpdateReqVO vo) {
        log.debug("SysCacheController cacheRefreshing() executed.param is {}", vo);
        if (mysqlSubstitute) {
            int expireSecond = XxlSsoCacheConfig.getCacheExpireMinute() * 60;
            vo.setExpireSecond(expireSecond);
            log.debug("###############SysCacheController cacheRefreshing in mysql, cacheKey:{},xxlSsoUser:{}", vo.getCacheKey(), vo.getXxlSsoUser());
            ReturnT<Boolean> result = sysCacheService.addOrUpdateSysCache(vo);
            if (ReturnT.FAIL_CODE != result.getCode() && result.getData()) {
                log.debug("###############SysCacheController cacheRefreshing in mysql, result:{}", result);
                log.info("SysCacheController cacheRefreshing() successfully executed.");
                return BaseResult.buildSuccess(result.getData());
            } else {
                log.error("SysCacheController cacheRefreshing() failed to execute.");
                return BaseResult.buildError("SysCacheController cacheRefreshing() failed to execute.");
            }
        } else {
            String cacheKey = vo.getCacheKey();
            XxlSsoUser xxlSsoUser = vo.getXxlSsoUser();
            int expireSecond = XxlSsoCacheConfig.getCacheExpireMinute() * 60;
            log.debug("###############ysCacheController cacheRefreshing in redis, cacheKey:{},xxlSsoUser:{}", vo.getCacheKey(), vo.getXxlSsoUser());
            JedisUtil.setObjectValue(cacheKey, xxlSsoUser, expireSecond);
            return BaseResult.buildSuccess(true);
        }
    }

    /**
     * 根据caheKey删除cache
     *
     * @return
     */
    @Override
    public BaseResult cacheEvictionByCacheKey(@RequestBody SysCacheKeyReqVO vo) {
        log.info("###################SysCacheController cacheEvictionByCacheKey() executed.param is {}", vo);
        if (mysqlSubstitute) {
            if (ObjectUtils.isEmpty(vo) || ObjectUtils.isEmpty(vo.getCacheKey())) {
                log.error("SysCacheController cacheEvictionByCacheKey() param cacheKey is null");
                return BaseResult.buildError("SysCacheController cacheEvictionByCacheKey() param cacheKey is null.");
            }
            ReturnT<Boolean> result = sysCacheService.deleteByCacheKey(vo.getCacheKey());
            if (ReturnT.FAIL_CODE != result.getCode() && result.getData()) {
                log.info("SysCacheController cacheEvictionByCacheKey() successfully executed.");
                return BaseResult.buildSuccess(result.getData());
            } else {
                log.error("SysCacheController cacheEvictionByCacheKey() failed to execute.");
                return BaseResult.buildError("SysCacheController cacheEvictionByCacheKey() failed to execute.");
            }
        } else {
            if (!ObjectUtils.isEmpty(vo) && !ObjectUtils.isEmpty(vo.getCacheKey())) {
                JedisUtil.del(vo.getCacheKey());
            }
            return BaseResult.buildSuccess(true);
        }
    }

    @Override
    public BaseResult put(SysCacheKeyCacheValueReqVO vo) {
        log.info("###################SysCacheController put() executed.param is {}", vo);
        String cacheKey = vo.getCacheKey();
        String cacheValue = vo.getCacheValue();
        JedisUtil.setStringValue(cacheKey, cacheValue, 60);
        return BaseResult.buildSuccess(true);
    }

    @Override
    public BaseResult<String> get(String storeKey) {
        log.info("###################SysCacheController get() executed.param is {}", storeKey);
        String value = JedisUtil.getStringValue(storeKey);
        return BaseResult.buildSuccess(value);
    }

    @Override
    public BaseResult<Boolean> removeByPrefix(String prefix) {
        log.info("###################SysCacheController removeByPrefix() executed.param is {}", prefix);
        Set<String> keys = JedisUtil.delByPrefix(prefix);
        log.info("###################SysCacheController removeByPrefix() executed.result is {}", keys);
        return BaseResult.buildSuccess(true);
    }
}
